/*
REWRITTEN BY XINEF
*/

#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "azjol_nerub.h"

DoorData const doorData[] =
{
    { GO_KRIKTHIR_DOORS,	DATA_KRIKTHIR_THE_GATEWATCHER_EVENT,	DOOR_TYPE_PASSAGE,		BOUNDARY_NONE },
    { GO_ANUBARAK_DOORS1,	DATA_ANUBARAK_EVENT,	DOOR_TYPE_ROOM,		BOUNDARY_NONE },
    { GO_ANUBARAK_DOORS2,	DATA_ANUBARAK_EVENT,	DOOR_TYPE_ROOM,		BOUNDARY_NONE },
    { GO_ANUBARAK_DOORS3,	DATA_ANUBARAK_EVENT,	DOOR_TYPE_ROOM,		BOUNDARY_NONE },
    { 0,					0,						DOOR_TYPE_ROOM,     BOUNDARY_NONE }
};

class instance_azjol_nerub : public InstanceMapScript
{
	public:
		instance_azjol_nerub() : InstanceMapScript("instance_azjol_nerub", 601) { }

		struct instance_azjol_nerub_InstanceScript : public InstanceScript
		{
			instance_azjol_nerub_InstanceScript(Map* map) : InstanceScript(map)
			{
				SetBossNumber(MAX_ENCOUNTERS);
				LoadDoorData(doorData);
				_krikthirGUID = 0;
				_hadronoxGUID = 0;
			};

			void OnCreatureCreate(Creature* creature)
			{
				switch (creature->GetEntry())
				{
					case NPC_KRIKTHIR_THE_GATEWATCHER:
						_krikthirGUID = creature->GetGUID();
						break;
					case NPC_HADRONOX:
						_hadronoxGUID = creature->GetGUID();
						break;
					case NPC_SKITTERING_SWARMER:
					case NPC_SKITTERING_INFECTIOR:
						if (Creature* krikthir = instance->GetCreature(_krikthirGUID))
							krikthir->AI()->JustSummoned(creature);
						break;
					case NPC_ANUB_AR_CHAMPION:
					case NPC_ANUB_AR_NECROMANCER:
					case NPC_ANUB_AR_CRYPTFIEND:
						if (Creature* hadronox = instance->GetCreature(_hadronoxGUID))
							hadronox->AI()->JustSummoned(creature);
						break;

				}
			}					

			void OnGameObjectCreate(GameObject* go)
			{
				switch (go->GetEntry())
				{
					case GO_KRIKTHIR_DOORS:
					case GO_ANUBARAK_DOORS1:
					case GO_ANUBARAK_DOORS2:
					case GO_ANUBARAK_DOORS3:
                        AddDoor(go, true);
						break;
				}
			}
			
			void OnGameObjectRemove(GameObject* go)
			{
				switch (go->GetEntry())
				{
					case GO_KRIKTHIR_DOORS:
					case GO_ANUBARAK_DOORS1:
					case GO_ANUBARAK_DOORS2:
					case GO_ANUBARAK_DOORS3:
                        AddDoor(go, false);
						break;
				}
			}

			bool SetBossState(uint32 id, EncounterState state)
			{
				return InstanceScript::SetBossState(id, state);
			}

			std::string GetSaveData()
			{
				std::ostringstream saveStream;
				saveStream << "A N " << GetBossSaveData();
				return saveStream.str();
			}

			void Load(const char* in)
			{
				if( !in )
					return;

				char dataHead1, dataHead2;
				std::istringstream loadStream(in);
				loadStream >> dataHead1 >> dataHead2;
				if (dataHead1 == 'A' && dataHead2 == 'N')
				{
					for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
					{
						uint32 tmpState;
						loadStream >> tmpState;
						if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
							tmpState = NOT_STARTED;
						SetBossState(i, EncounterState(tmpState));
					}
				}
			}

		private:
			uint64 _krikthirGUID;
			uint64 _hadronoxGUID;
		};

		InstanceScript* GetInstanceScript(InstanceMap *map) const
		{
			return new instance_azjol_nerub_InstanceScript(map);
		}
};

class spell_azjol_nerub_fixate : public SpellScriptLoader
{
    public:
        spell_azjol_nerub_fixate() : SpellScriptLoader("spell_azjol_nerub_fixate") { }

        class spell_azjol_nerub_fixate_SpellScript : public SpellScript
        {
            PrepareSpellScript(spell_azjol_nerub_fixate_SpellScript);

            void HandleScriptEffect(SpellEffIndex effIndex)
            {
				PreventHitDefaultEffect(effIndex);
				if (Unit* target = GetHitUnit())
					target->CastSpell(GetCaster(), GetEffectValue(), true);
            }

            void Register()
            {
                OnEffectHitTarget += SpellEffectFn(spell_azjol_nerub_fixate_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
            }
        };

        SpellScript* GetSpellScript() const
        {
            return new spell_azjol_nerub_fixate_SpellScript();
        }
};

class spell_azjol_nerub_web_wrap : public SpellScriptLoader
{
	public:
		spell_azjol_nerub_web_wrap() : SpellScriptLoader("spell_azjol_nerub_web_wrap") { }

		class spell_azjol_nerub_web_wrap_AuraScript : public AuraScript
		{
			PrepareAuraScript(spell_azjol_nerub_web_wrap_AuraScript);

			void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
			{
				Unit* target = GetTarget();
				if (!target->HasAura(SPELL_WEB_WRAP_TRIGGER))
					target->CastSpell(target, SPELL_WEB_WRAP_TRIGGER, true);
			}

			void Register()
			{
				OnEffectRemove += AuraEffectRemoveFn(spell_azjol_nerub_web_wrap_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_ROOT, AURA_EFFECT_HANDLE_REAL);
			}
		};

		AuraScript* GetAuraScript() const
		{
			return new spell_azjol_nerub_web_wrap_AuraScript();
		}
};

void AddSC_instance_azjol_nerub()
{
   new instance_azjol_nerub();
   new spell_azjol_nerub_fixate();
   new spell_azjol_nerub_web_wrap();
}
